// pages/exams/exams.js
var rpn = require("../../utils/rpn.js");
const app = getApp();
var inputRes = "";
var isRight = null;
var questions = [];
var total_time = 8 * 60 * 1000 //8分钟倒计时
Page({
  //页面的初始数据
  data:{
    readyVal: '0',
    sign: null,
    curVal: '0',
    newFlag: true,
    grade: 0,
    index: 0,
    ans: "",//用户输入答案
    btn: "下一题",//按钮显示
    inputError: "",//输入空白提示
    formula: "",//生成的算式
    res: null,//正确答案
    time: "8分0秒",//倒计时
    clock: 480,
    clocks: 0
  },

  //生命周期函数--监听页面加载，options为页面跳转所带来的参数
  onLoad:function(options){
    this.countdown();
    //console.log(options);
    app.globalData.num = 0;
    app.globalData.wrongPaper.equation = [];
    app.globalData.wrongPaper.input = [];
    app.globalData.wrongPaper.result = [];
    app.globalData.wrongPaper.right = [];//更新全局变量
    //app.globalData.inputnum = 20;
    app.globalData.score = 0;
    this.data.grade = options.grade;//上级界面传入的年级
    //console.log(this.data.grade);
    questions = this.generate(this.data.grade);
    //console.log(questions);
    if (questions) {
      var formu_result = questions[this.data.index];
      var formu = formu_result[0];
      var result = formu_result[1];
      this.setData({
        formula: formu,
        res: result,
      })
    }
  },

  //输入答案
  intans: function (e) {
    this.setData({
      ans: e.detail.value
    })
  },

  //确认,判断正误并进入下一题或提交
  btnClick: function (e) {
    //console.log("题：" + this.data.index + "answer:" + this.data.ans)
    if (this.data.ans.length == 0) {
      this.setData({
        inputError: "输入答案不能为空"
      })
      return false;
    }
    else {
      if (this.data.index < app.globalData.inputnum - 1) {
        this.setData({
          index: this.data.index + 1
        })
        this.judge();
        var that = this;
        setTimeout(function () {
          if (that.data.index < app.globalData.inputnum - 1) {
            that.setData({
              btn: "下一题",
              inputError: "",
            })
          }
          else {
            that.setData({
              btn: "提交",
              inputError: ""
            })
          }
          
          that.setData({
            ans: "",
          })

          var formu_result = questions[that.data.index];
          var formu = formu_result[0];
          var result = formu_result[1];
          that.setData({
            formula: formu,
            res: result,
          })
        }, 100)
      }
      else {
        this.judge();
        wx.reLaunch({
          url: '../sum/sum',
        })
        /*wx.navigateTo({
          url: '../pages/sum/sum',
        })*/
      }
    }
  },

  //判断正误
  judge: function () {
    if (parseInt(this.data.ans) == this.data.res) {
      isRight = 1;
    }
    else {
      isRight = 0;
    }
    app.globalData.num = app.globalData.num + 1;
    app.globalData.wrongPaper.equation[app.globalData.num - 1] = this.data.formula;
    app.globalData.wrongPaper.input[app.globalData.num - 1] = this.data.ans;
    app.globalData.wrongPaper.result[app.globalData.num - 1] = this.data.res;
    app.globalData.wrongPaper.right[app.globalData.num - 1] = isRight;
  },

  f1: function (s) {
    //搜索括号算式
    var ss = s.match(/\(\d+[\+\-\*/\d]+\)/);
    if (ss) return ss[0];
    else return null;
  },
  f2: function (s) {
    //搜索乘除法算式
    var ss = s.match(/\d+[\*/]\d+/);
    if (ss) return ss[0];
    else return null;
  },
  f3: function (s) {
    //搜索加减法算式
    var ss = s.match(/\d+[\+\-]\d+/);
    if (ss) return ss[0];
    else return null;
  },
  f4: function (s) {
    //搜索加减乘除算式
    var ss = s.match(/\d+[\+\-\*/\d]+/);
    if (ss) return ss[0];
    else return null;
  },
  isResultOk: function (str, result) {
    //验证算式结果是否正确
    //console.log(str);
    var tmp = rpn.calCommonExp(str);
    //console.log(result, tmp);
    if (tmp === Infinity || isNaN(tmp)) return false;
    else return result[0] <= tmp <= result[1];
  },
  isMultDivOk: function (s, result) {
    //验证乘除法正确性
    if (s.match(/\//)) {
      var ss = s.split(/\//);
      if (rpn.calCommonExp(ss[1]) === 0) return false;
      else {
        if (this.isResultOk(s, result) && parseInt(rpn.calCommonExp(ss[0]) % rpn.calCommonExp(ss[1])) === 0)
          return true;
        else return false;
      }
    }
    if (s.match(/\*/)) {
      return this.isResultOk(s, result);
    }
    return true;
  },
  is_addcarry: function (a, b) {
    //判断加法进位
    while (a > 0 && b > 0) {
      var aa = Math.floor(a % 10);
      var bb = Math.floor(b % 10);
      if (aa + bb >= 10) return true;
      a = Math.floor(a / 10);
      b = Math.floor(b / 10);
    }
    return false;
  },
  is_addnocarry: function (a, b) {
    return !(this.is_addcarry(a, b));
  },
  is_abdication: function (a, b) {
    //判断减法退位
    //console.log(a);
    //console.log(b);
    while (a > 0 && b > 0) {
      var aa = Math.floor(a % 10);
      var bb = Math.floor(b % 10);
      if (aa < bb) return true;
      a = Math.floor(a / 10);
      b = Math.floor(b / 10);
    }
    return false;
  },
  is_noabdication: function (a, b) {
    return !(this.is_abdication(a, b));
  },
  is_multcarry: function (a, b) {
    //判断乘法进位
    var B = b;
    while (a > 0) {
      var aa = Math.floor(a % 10);
      b = B;
      while (b > 0) {
        var bb = Math.floor(b % 10);
        if (aa * bb >= 10) return true;
        b = Math.floor(b / 10);
      }
      a = Math.floor(a / 10);
    }
    return false;
  },
  is_int: function (n) {
    //判断n是否为整数
    return Math.floor(n) === n;
  },
  isAddSub: function (s, result, carry, abdication) {
    //判断加减法正确性
    var tmp = s.split(/[\-\+]/g);
    if (this.isResultOk(s, result)) {
      //console.log(tmp);
      //console.log(s);
      tmp[0] = rpn.calCommonExp(tmp[0]);
      tmp[1] = rpn.calCommonExp(tmp[1]);
      if (s.match(/\+/)) {
        //console.log(s, carry);
        if (carry === 1) return true;
        if (carry === 2) return this.is_addcarry(tmp[0], tmp[1]);
        if (carry === 3) return this.is_addnocarry(tmp[0], tmp[1]);
      }
      if (s.match(/\-/)) {
        //console.log(s, abdication);
        if (abdication === 1) return true;
        if (abdication === 2) return this.is_abdication(tmp[0], tmp[1]);
        if (abdication === 3) return this.is_noabdication(tmp[0], tmp[1]);
      }
      return false;
    }
    return true;
  },
  validator2: function (s, result, carry, abdication) {
    //分解加减乘除法计算结果并检验
    while (this.f2(s)) {
      //乘除法验证
      var f = this.f2(s);
      if (this.isMultDivOk(f, result)) {
        var r = rpn.calCommonExp(f);
        s = s.replace(f, r);
      }
      else return false;
    }
    while (this.f3(s)) {
      //加减法验证
      var f = this.f3(s);
      if (this.isAddSub(f, result, carry, abdication)) {
        //console.log(f);
        //console.log(result);
        var r = rpn.calCommonExp(f);
        s = s.replace(f, r);
      }
      else return false;
    }
    return s;
  },
  validator1: function (s, result, carry, abdication) {
    //提取括号内算式，递归给validator2进行验证
    while (this.f1(s)) {
      var fa = this.f1(s);
      var fb = this.f4(fa);
      var r = this.validator2(fb, result, carry, abdication);
      if (r) s = s.replace(fa, r);
      else return false;
    }
    return s;
  },
  validator: function (s, result, carry, abdication) {
    //算式分解校验器
    if (this.isResultOk(s, result)) {
      if (this.f1(s)) {
        s = this.validator1(s, result, carry, abdication);
        if (s) return this.validator2(s, result, carry, abdication);
        else return false;
      }
      else return this.validator2(s, result, carry, abdication);
    }
    else return false;
  },
  randomNum: function (mn, mx) {//随机范围:[mn, mx)
    mn = Math.floor(mn);
    mx = Math.floor(mx);
    return (mn + Math.round(Math.random() * (mx - mn)));
  },
  getRandomNum: function (list, step) {//
    var newList = new Array();
    for (var i = 0; i <= step; i++) {
      newList[i] = this.randomNum(list[i][0], list[i][1]);
    }
    return newList;
  },
  getSymbol: function (sym) {
    //获得运算符号
    if (sym === 1) return "+";
    if (sym === 2) return "-";
    if (sym === 3) return "*";
    if (sym === 4) return "/";
  },
  getRandomSymbols: function (symbols, step) {
    //返回一组运算符号
    var newList = new Array();
    for (var i = 0; i < step; i++) {
      var index = this.randomNum(0, symbols[i].length - 1);
      newList[i] = symbols[i][index];
    }
    return newList;
  },
  getRandomBracket: function (step) {
    while (true) {
      var k = this.randomNum(0, step * 2 - 2);
      if (!(k % 2)) return k;
    }
  },
  getPSMstr: function (formulas, symbols, step, is_bracket) {
    //生成算式题
    var ss = "";
    //console.log(symbols);
    var sym = this.getRandomSymbols(symbols, step);
    //console.log(sym);
    for (var i = 0; i < step; i++) {
      formulas.splice(i * 2 + 1, 0, this.getSymbol(sym[i]));
    }
    //console.log(formulas);
    if (is_bracket) {
      var k = this.getRandomBracket(step);
      for (var i = 0; i < 2; i++) {
        if (i === 0) formulas.splice(k + 4 * i, 0, "(");
        else formulas.splice(k + 4 * i, 0, ")");
      }
    }
    for (var i = 0; i < formulas.length; i++) {
      ss += formulas[i];
    }
    return ss;
  },
  getMoreStep: function (formulas, result, symbols, step, carry, abdication, is_bracket) {
    //formulas:整数算数项
    //result:最终结果范围
    //symbols:每步题的算数符号
    //step:步数
    //carry:加法是否进位
    //abdication:减法是否退位
    //is_bracket:是否包含括号
    //return: str 一道符合规则的口算运算题
    var f = this.getRandomNum(formulas, step);
    //console.log(f);
    var str = this.getPSMstr(f, symbols, step, is_bracket);
    //console.log(step, f, symbols, str, result);
    if (this.validator(str, result, carry, abdication)) return str;
    else return false;
  },
  getOne: function (formulas, signum, result, carry, abdication) {
    //根据条件生成一道一步算式题
    //formulas:给定的单步加法的两个值
    //signum:加减乘除
    //result:结果范围
    //carry:加法进位
    //return: bool or str 成功返回一个符合条件的加法算数题str，失败返回false
    var formul = false;
    while (formul == false) {
      formul = this.getMoreStep(formulas, result, signum, 1, carry, abdication, 0);
    }
    return formul;
  },
  getformulas: function (step, signum, multistep, carry, abdication) {
    var f = new Array();
    for (var i = 0; i <= step; i++) {
      f[i] = multistep[i];
    }
    var formulas = new Array();
    if (step == 1) {
      formulas[0] = false;
      while (formulas[0] == false || !(multistep[step + 1][0] <= formulas[1] <= multistep[step + 1][1])) {
        formulas[0] = this.getOne(f, signum, multistep[step + 1], carry, abdication);
        if (formulas[0] != false) formulas[1] = rpn.calCommonExp(formulas[0]);
      }
    }
    else {
      formulas[0] = false;
      while (formulas[0] == false || multistep[step + 1][0] > formulas[1] || formulas[1] > multistep[step + 1][1]) {
        formulas[0] = this.getMoreStep(f, multistep[step + 1], signum, step, carry, abdication, 0);
        if (formulas[0] != false) formulas[1] = rpn.calCommonExp(formulas[0]);
        //console.log(formulas[1], (!(multistep[step + 1][0] <= formulas[1] <= multistep[step + 1][1])));
      }
    }
    //console.log(formulas[0]);
    formulas[0] += "=";
    return formulas;
  },
  generate_data: function (number, step, signum, multistep, carry, abdication) {
    //根据条件生成口算题
    //number：口算题数
    //step：口算题步数
    //signum：每一步的符号（eg.[[1,2],[1,2,3]]:第一步只能是+或-，第二步可以是+、-、*）
    //multistep：运算项及结果范围
    //carry：是否进位，1随机，2进位，3不进位
    //abdication：是否退位, 1随机，2退位，3不退位
    var slist = new Array();
    var k = 0;
    while (true) {
      var formulas = this.getformulas(step, signum, multistep, carry, abdication);
      if (formulas) {
        slist.push(formulas);
        k++;
      }
      if (k === number) break;
    }
    return slist;
  },
  generate: function (opt) {
    var number = app.globalData.inputnum;
    //console.log(number);
    //console.log(opt);
    var problem_set = new Array();
    var step;
    var signum = new Array();
    var multistep = new Array();
    var carry;
    var abdication;
    switch (opt) {
      case '1':
        step = 1;
        signum = [[1, 2],];
        multistep = [[1, 9], [1, 9], [1, 9]];
        carry = 3;
        abdication = 3;
        //console.log(multistep);
        problem_set = this.generate_data(number, step, signum, multistep, carry, abdication);
        //console.log(problem_set);
        break;
      case '2':
        step = 1;
        signum = [[1, 2, 3],];
        multistep = [[1, 100], [1, 100], [1, 100]];
        carry = 1;
        abdication = 1;
        problem_set = this.generate_data(number, step, signum, multistep, carry, abdication);
        break;
      case '3':
        step = 2;
        signum = [[1, 2, 3], [1, 2]];
        multistep = [[1, 100], [1, 100], [1, 100], [1, 999]];
        carry = 1;
        abdication = 1;
        problem_set = this.generate_data(number, step, signum, multistep, carry, abdication);
        break;
      case '4':
        step = 2;
        signum = [[1, 2, 3], [1, 2, 3, 4]];
        multistep = [[1, 100], [1, 100], [1, 100], [1, 999]];
        carry = 1;
        abdication = 1;
        problem_set = this.generate_data(number, step, signum, multistep, carry, abdication);
        break;
      case '5':
        step = 2;
        signum = [[1, 2, 3, 4], [1, 2, 3, 4]];
        multistep = [[1, 100], [1, 100], [1, 999], [1, 999]];
        carry = 1;
        abdication = 1;
        problem_set = this.generate_data(number, step, signum, multistep, carry, abdication);
        break;
      case '6':
        var step = 2;
        var signum = [[1, 2, 3, 4], [1, 2, 3, 4]];
        var multistep = [[-100, 100], [-100, 100], [-999, 999], [-999, 999]];
        var carry = 1;
        var abdication = 1;
        problem_set = this.generate_data(number, step, signum, multistep, carry, abdication);
        break;
      //default: console.log(opt);
    }
    return problem_set;
  }, 

  //倒计时时界面跳转
  countdown: function() {
    this.subcountdown();
    /*var that = this;
    var timer = that.data.timer;
    var time = that.dateformat(timer)
    that.setData({
      time: that.data.time,
    })
    that.setData({
      timer: setInterval(function() {
        timer--;
        console.log(timer);
        that.setData({
          timer: timer,
          time: that.dateformat(timer)
        })
        if (timer == 0) {
          //倒计时结束,关闭计时器
          clearInterval(that.data.timerName);
          wx.reLaunch({
            url: '../pages/sum/sum',
          })
        }
        that.data.timer = 480;
      },1000)
    })*/
  },

  subcountdown: function() {
    var that = this
    //console.log('countdown=')
    var time = this.dateformat(total_time)
    //console.log('time' + time)
    that.setData({
      time: time,
    })
    if (total_time <= 0) {
      that.setData({
        time: "答题结束"
      });
      //timeout，跳出递归
      setTimeout(function () {
        wx.navigateTo({
          url: '../sum/sum',
        })
      }, 1000)
      return
    }
    setTimeout(function () {
      total_time = total_time - 1000;
      console.log(total_time);
      that.countdown();
    }, 1000)
  },

  //倒计时时钟格式
  dateformat: function(time) {
    //总秒数
    var second = Math.floor(time/1000);
    var min = Math.floor(second/60);
    var sec = Math.floor(second - min*60);
    return min + "分" + sec + "秒";
  },

  //倒计时强制跳转
  redirect: function() {
    setTimeout(function() {
      wx.reLaunch({
        url: '../sum/sum',
      })
      /*wx.reLaunch({
        url: '../sum/sum',
      })*/
    }, 902000)
  },

  //生命周期函数--监听页面初次渲染完成
  onReady:function(){
    
  },

  //生命周期函数--监听页面显示
  onShow:function(){
    
  },

  //生命周期函数--监听页面隐藏
  onHide:function(){
    
  },

  //生命周期函数--监听页面卸载
  onUnload:function(){
    
  },

  //页面相关事件处理函数--监听用户下拉动作
  onPullDownRefresh: function () {

  },

  //页面上拉触底事件的处理函数
  onReachBottom: function () {

  },

  //用户点击右上角分享
  onShareAppMessage: function () {

  }
})